#include "bsp_led188.h"
#include "systick.h"
/***********************
1. 数码管从0%显示到100% （闪电亮起）
2. 闪电关闭
3. 数码管从100%显示到0%

把不希望亮的引脚，配置为高阻输入
************************/
#ifndef u8
#define u8 uint8_t
#endif

#ifndef u16
#define u16 uint16_t
#endif

#ifndef u32
#define u32 uint32_t
#endif
//宏定义五个灯的RCU、port、pin
#define LED188_RCU RCU_GPIOE

#define LED188_1_PORT         GPIOE
#define LED188_1_PIN          GPIO_PIN_15
#define LED188_2_PORT         GPIOE
#define LED188_2_PIN          GPIO_PIN_13
#define LED188_3_PORT         GPIOE
#define LED188_3_PIN          GPIO_PIN_11
#define LED188_4_PORT         GPIOE
#define LED188_4_PIN          GPIO_PIN_9
#define LED188_5_PORT         GPIOE
#define LED188_5_PIN          GPIO_PIN_7
//推挽输出设置
#define OUT1(bit) gpio_mode_set(LED188_1_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED188_1_PIN);gpio_bit_write(LED188_1_PORT, LED188_1_PIN, bit?SET:RESET)
#define OUT2(bit) gpio_mode_set(LED188_2_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED188_2_PIN);gpio_bit_write(LED188_2_PORT, LED188_2_PIN, bit?SET:RESET)
#define OUT3(bit) gpio_mode_set(LED188_3_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED188_3_PIN);gpio_bit_write(LED188_3_PORT, LED188_3_PIN, bit?SET:RESET)
#define OUT4(bit) gpio_mode_set(LED188_4_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED188_4_PIN);gpio_bit_write(LED188_4_PORT, LED188_4_PIN, bit?SET:RESET)
#define OUT5(bit) gpio_mode_set(LED188_5_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED188_5_PIN);gpio_bit_write(LED188_5_PORT, LED188_5_PIN, bit?SET:RESET)


#define HZ_PIN(port,pin) gpio_mode_set(port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, pin)
//使用宏定义将上述所有引脚配置为浮空输入(高阻态)模式
#define HZ_ALL() 					\
HZ_PIN(LED188_1_PORT, LED188_1_PIN);\
HZ_PIN(LED188_2_PORT, LED188_2_PIN);\
HZ_PIN(LED188_3_PORT, LED188_3_PIN);\
HZ_PIN(LED188_4_PORT, LED188_4_PIN);\
HZ_PIN(LED188_5_PORT, LED188_5_PIN);\

static void GPIO_config_output(rcu_periph_enum rcu, uint32_t port, uint32_t pin) {
	// 1. 时钟初始化
	rcu_periph_clock_enable(rcu);
	// 2. 配置GPIO 输入输出模式
	gpio_mode_set(port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, pin);
	// 3. 配置GPIO 输出选项
	gpio_output_options_set(port, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, pin);
	//4.默认输出低电平
	gpio_bit_write(port, pin, RESET);
}

void LED188_init(){
    GPIO_config_output(LED188_RCU, LED188_1_PORT, LED188_1_PIN);
    GPIO_config_output(LED188_RCU, LED188_2_PORT, LED188_2_PIN);
    GPIO_config_output(LED188_RCU, LED188_3_PORT, LED188_3_PIN);
    GPIO_config_output(LED188_RCU, LED188_4_PORT, LED188_4_PIN);
    GPIO_config_output(LED188_RCU, LED188_5_PORT, LED188_5_PIN);
    //全部设置为高阻态
    HZ_ALL();
}
//单独点亮百位
static void LED188_hun(){
    //首先全部设为高阻态
    //将这三个引脚这位推挽输出模式
    //只需将引脚4拉低，引脚3和引脚2拉高
    HZ_ALL();
    OUT4(0);
    OUT3(1);
    OUT2(1);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//  19  18      17  16      15  14  13  12  11  10   9   8      7   6   5   4   3   2   1   0   //
//  K2  K1  |   C1  B1  |   XX  G2  F2  E2  D2  C2  B2  A2  |  XX  G3  F3  E3  D3  C3  B3  A3   //
//百分号 闪电     百位                     十位                               个位
//点灯只需将对应位置1即可
//////////////////////////////////////////////////////////////////////////////////////////////////
//总结一个显示数字内容的段码数组
//                      0    1    2    3    4    5    6    7    8   9
uint8_t seg_num[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//状态表达
#define A3 (1<<0)
#define B3 (1<<1)
#define C3 (1<<2)
#define D3 (1<<3)
#define E3 (1<<4)
#define F3 (1<<5)
#define G3 (1<<6)

#define A2 (1<<8)
#define B2 (1<<9)
#define C2 (1<<10)
#define D2 (1<<11)
#define E2 (1<<12)
#define F2 (1<<13)
#define G2 (1<<14)

#define B1 (1<<16)
#define C1 (1<<17)

#define K1 (1<<18)
#define K2 (1<<19)
//将参数转换为所需灯的比特信息
uint32_t states = 0x000000;//定义一个32位的变量，用于存储每一个灯的状态
//显示123
void LED188_set_num(uint8_t num){
  //将数字限制在[0,199]
  if(num > 199) num = 199;
  //百位最大只能为1,如果大于100则百位显示1
  if(num >= 100){
    states |=((uint32_t)0x030000); 
  }//否则熄灭
  else{
    states &=~((uint32_t)0x030000);
  }
  //取出十位
  uint8_t ten = num/10%10;
  //先将states的十位信息清零
  //将十位的位信息存储到states中
  states &=~((uint32_t)0x00FF00);
  states |=((uint32_t)(seg_num[ten]<<8));
  //个位同理，先取出个位
  uint8_t one = num%10;
  states &=~((uint32_t)0x0000FF);
  states |=(uint32_t)(seg_num[one]);
}
void LED188_clear_num(){
	//息屏 全部拉高/全部拉低
  states |= 0xFFFFFF;
}
//显示百分号
void LED188_set_percent(uint8_t enable){
  //判断是否使能显示，使能就置1
  if(enable) states |=K2;
  else states &=~K2;
}
//显示闪电
void LED188_set_charge(uint8_t enable){
  //判断是否使能显示，使能就置1
  if(enable) states |=K1;
  else states &=~K1;
}
//按5*5表格 按行点亮每一部分的灯
void LED188_display(){
  static u8 i = 1;
  //全部高阻
  HZ_ALL();
  //5部分
  switch(i++){
    case 1: 
      //先拉低引脚1  再拉高其他引脚
      OUT1(0);
      if(states & B3)OUT2(1);//对应5*5表格B3
      if(states & D3)OUT3(1);//对应5*5表格D3
      if(states & F3)OUT4(1);//对应5*5表格F3
      if(states & G3)OUT5(1);//对应5*5表格G3
      break;
    case 2:
      //先拉低引脚2 再拉高其他引脚
      OUT2(0);
      if(states & A3)OUT1(1);//对应5*5表格A3
      if(states & B2)OUT3(1);//对应5*5表格B2
      if(states & D2)OUT4(1);//对应5*5表格D2
      if(states & E2)OUT5(1);//对应5*5表格E2
      break;
    case 3:
      OUT3(0);
      if(states & C3)OUT1(1);//对应5*5表格C3
      if(states & A2)OUT2(1);//对应5*5表格A2
      if(states & C2)OUT4(1);//对应5*5表格C2
      if(states & F2)OUT5(1);//对应5*5表格F2
      break;
    case 4:
      OUT4(0);
      if(states & E3)OUT1(1);//对应5*5表格E3
      if(states & C1)OUT2(1);//对应5*5表格C1
      if(states & B1)OUT3(1);//对应5*5表格B1
      if(states & G2)OUT5(1);//对应5*5表格G2
      break;
    case 5:
      OUT5(0);
      //OUT1(1); //硬件没灯
      if(states & K2)OUT2(1);//对应5*5表格K2
      if(states & K1)OUT3(1);//对应5*5表格K1
     // OUT4(1);  //硬件没灯
			i = 1;  // 重置为1
      break;
  }
}
